#include <iostream>
#include <string>

using namespace std;

typedef string arrType[10];

using arrType1 = string[10];

string (*funcPointer(int a))[10];

string (&funcRef(string param))[10];

auto funcPtr(int param) -> string (*) [10];

void printItem(string (*arr)[10]);

void printItem(string (&arr)[10]);

int calcRef1(int&, int&);

int calcRef2(const int&, const int&);

int calcPtr1(char*, char*);

int calcPtr2(const char*, const char*);

int calcPtr3(char* const, char* const);

int main(void)
{
    string (*ret1)[10] = funcPointer(1);
    string (&ret2)[10] = funcRef("abc");
    printItem(ret1);
    printItem(ret2);

    arrType *ret3 = funcPointer(3);
    printItem(ret3);

    arrType1 *ret4 = funcPointer(3);
    printItem(ret3);

    auto funcPtr = &funcPointer;
    arrType *ret5 = funcPtr(3);
    printItem(ret5);

    char *pParam1 = nullptr;
    char *pParam2 = nullptr;
    int a = 0;
    int b = 0;

    calcRef1(a, b);
    calcRef2(a, b);
    calcPtr1(pParam1, pParam2);
    calcPtr2(pParam1, pParam2);
    calcPtr3(pParam1, pParam2);

    return 0;
}

string (*funcPointer(int a))[10]
{
    static string arr[10];
    arr[0] = std::string("array 1");
    return &arr;
}

string (&funcRef(string param))[10]
{
    static string arr[10];
    arr[0] = std::string("array 2");
    return arr;
}

void printItem(string (*arr)[10])
{
    cout << "print func 1, the first item is "
         << (*arr)[0]
         << endl;
}

void printItem(string (&arr)[10])
{
    cout << "print func 2, the first item is "
         << arr[0]
         << endl;
}

int calcRef1(int&, int&)
{
    cout << "calcRef1 called"
         << endl;
    return 0;
}

int calcRef2(const int&, const int&)
{
    cout << "calcRef2 called"
         << endl;
    return 0;
}

int calcPtr1(char*, char*)
{
    cout << "calcPtr1 called"
         << endl;
    return 0;
}

int calcPtr2(const char*, const char*)
{
    cout << "calcPtr2 called"
         << endl;
    return 0;
}

int calcPtr3(char* const, char* const)
{
    cout << "calcPtr3 called"
         << endl;
    return 0;
}